//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "tyr_airdrop\fn_executeDrop.sqf"
#include <core_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

if (GVAR(TRANSPORTER_IN_THE_AIR)) exitWith {};
if (GVAR(AVAILABLE_VEHICLES) == 0) exitWith {};
_this spawn {
	TRACE_1("Spawn Start",_this);
	private ["_unit","_position","_vec_type","_type","_class","_drop_point","_start_point","_vehicle","_dir","_grp","_i","_wp","_prev","_dist","_params","_object","_chute","_is_ammo","_para_pos"
			,"_last_dist","_dist","_driver","_parachute_type"];
	DEFAULT_PARAM(_vec_type,0,GVAR(DROPVEHICLE_TYPE_WEST));
	DEFAULT_PARAM(_unit,1,objNull);
	DEFAULT_PARAM(_position,2,[]);
	DEFAULT_PARAM(_type,3,"");
	DEFAULT_PARAM(_class,4,"");

	GVAR(TRANSPORTER_IN_THE_AIR) = true;
	publicVariable QGVAR(TRANSPORTER_IN_THE_AIR);
	_vehicle = objNull;
	
	#define __disabled_vehicle (isNull _vehicle || {!(alive _vehicle)} || {!(canMove _vehicle)} || {isNull (driver _vehicle)} || {!alive (driver _vehicle)})
	#define __delete_vehicle _vehicle setDamage 1.1; { deleteVehicle _x } foreach units _grp; deleteVehicle _vehicle; _grp call mso_fnc_deleteGroup;
	//#define __inform_player(text) [2,[_driver,_unit,#text],QUOTE(FUNC(informPlayer))] call mso_core_fnc_ExMP;
	#define __inform_player(text) ["TYR",QGVAR(INFORMPLAYER),[_driver,_unit,#text],"player"] call IFUNC(rpc);
	
	if (!isNil "server" && {IS_OBJECT(server)} && {!isNull server}) then {
		//[2,[server,_unit,"STR_TYR_DROP_REQUESTRECEIVED"],QUOTE(FUNC(informPlayer))] call mso_core_fnc_ExMP;
		["TYR",QGVAR(INFORMPLAYER),[server,_unit,"STR_TYR_DROP_REQUESTRECEIVED"],"player"] call IFUNC(rpc);
	} else {
		["TYR",QGVAR(INFORMPLAYER),[_unit,_unit,"STR_TYR_DROP_REQUESTRECEIVED"],"player"] call IFUNC(rpc);
	};
	sleep 10 + random(6);
	
	_parachute_type = missionNameSpace getVariable [format[QGVAR(PARACHUTE_TYPE_%1),side _unit],GVAR(PARACHUTE_TYPE_WEST)];
	
	_drop_point = [_position, GVAR(MAX_DROP_DIST)] call mso_core_fnc_GetRanPointCircle;
	_start_point = GVAR(AIR_DROP_START_POINT);
	if (count _start_point <= 0) then {
		_start_point = [_position, (GVAR(MAP_SIZE) / 3)] call mso_core_fnc_getranpointcircleouterair;
	};
	_start_point set [2, (GVAR(FLY_IN_HEIGHT) + 100)];
	_dir =  [_start_point,_drop_point] call mso_core_fnc_DirTo;

	TRACE_1("Vehicle",ARR_5(_drop_point,_dir,_start_point,_type,_class));
	_vehicle = createVehicle [_vec_type,_start_point,[], _dir, "FLY"];
	_vehicle setDir _dir;
	_vehicle setVelocity [150,0,5];
	createVehicleCrew _vehicle;
	_grp = group (driver _vehicle);
	{
		if ((driver _vehicle == _x) || (commander _vehicle == _x)) then {
			_x disableAI "TARGET";
			_x disableAI "AUTOTARGET";
		};
	} foreach (crew _vehicle);
	_grp allowFleeing 0;
	_grp setCombatMode "YELLOW";
	_grp setSpeedMode "FULL";
	_grp setBehaviour "CARELESS";
	for "_i" from ((count (waypoints _grp)) - 1) to 0 step -1 do {
		deleteWaypoint [_grp,_i];
	};
	_driver = driver _vehicle;
	__inform_player(STR_TYR_DROP_VEHICLETAKEOFF)

	_wp = _grp addWaypoint [_drop_point,0];
	_wp setWaypointType "MOVE";
	_wp setWaypointSpeed "FULL";
	_wp setWaypointBehaviour "CARELESS";

	_wp = _grp addWaypoint [_start_point,0];
	_wp setWaypointType "MOVE";
	_wp setWaypointSpeed "FULL";
	_wp setWaypointBehaviour "CARELESS";
	_wp setWaypointStatements ["true","private ['_veh','_grp']; _veh = vehicle this; _grp = group this; _veh setDamage 1.1; { deleteVehicle _x } foreach thislist; deleteVehicle _veh; _grp call mso_fnc_deleteGroup;"];

	_vehicle flyInHeight GVAR(FLY_IN_HEIGHT);
	_grp setCurrentWaypoint [_grp, 0];
	(driver _vehicle) doMove _drop_point;

	_last_dist = 0;
	_dist = 0; 
	waituntil {
		sleep 9.543;
		_dist = ([_vehicle, _drop_point] call mso_core_fnc_grounddist);
		if (_dist > _last_dist) then {
			(driver _vehicle) doMove _drop_point;
			_last_dist = _dist;
		};
		(
			__disabled_vehicle ||
			{([_vehicle, _drop_point] call mso_core_fnc_grounddist < 1000)}
		)
	};
	TRACE_1("Disabled",ARR_7(__disabled_vehicle, _vehicle, _grp, getdir _vehicle, crew _vehicle,(alive _vehicle),(canMove _vehicle)));

	if (__disabled_vehicle) then {
		GVAR(AVAILABLE_VEHICLES) = GVAR(AVAILABLE_VEHICLES) - 1;
		publicVariable QGVAR(AVAILABLE_VEHICLES);
		__inform_player(STR_TYR_DROP_VEHICLEDESTROYED)
		sleep 5;
		__delete_vehicle
	} else {
		__inform_player(STR_TYR_DROP_VEHICLEARRIVING)
		waituntil {
			(
				__disabled_vehicle ||
				{([_vehicle, _drop_point] call mso_core_fnc_grounddist < 200)}
			)
		};
		TRACE_1("Disabled",__disabled_vehicle);

		if (__disabled_vehicle) then {
			GVAR(AVAILABLE_VEHICLES) = GVAR(AVAILABLE_VEHICLES) - 1;
			publicVariable QGVAR(AVAILABLE_VEHICLES);
			__inform_player(STR_TYR_DROP_VEHICLEDESTROYED)
			sleep 5;
			__delete_vehicle
		} else {
			_prev = 1000;
			_dist = 999;
			while { _dist < _prev && !__disabled_vehicle } do { _prev = _dist; _dist = _vehicle distance _drop_point; sleep 0.31; };

			__inform_player(STR_TYR_DROP_VEHICLEDROPPING)
			_object = objNull;
			_is_ammo = false;
			switch (_type) do {
				// Vehicle
				case "1": {

				};
				// Static
				case "2": {
				
				};
				// Ammo
				default {
					_object = _class;
					_is_ammo = true;
				};		
			};
			_para_pos = _vehicle modelToWorld [-10,0,-15];
			if (!_is_ammo) then {
				_object = createVehicle [_class,_para_pos,[], getdir _vehicle, "NONE"];
				_para_pos = _object modelToWorld [0,0,2];
				
			};
			TRACE_1("Object",ARR_2(_object,_para_pos));
			
			_chute = createVehicle [_parachute_type,_para_pos,[], getdir _vehicle, "NONE"];
			_chute setPos _para_pos;
			if (!_is_ammo) then {
				_object attachTo [_chute,[0,0,0]];
			};
			TRACE_1("Parachute",ARR_2(_chute,_para_pos));
			
			_params = [];
			_params set [0, _object];
			_params set [1, _drop_point];
			_params set [2, 50];
			_params set [3, ""];
			_params set [4, _chute];
			_params set [5, _is_ammo];
			_params spawn FUNC(mando_chute);
		};
		
		(driver _vehicle) doMove _start_point;
		sleep 10;
		__inform_player(STR_TYR_DROP_VEHICLELEAVING)
		waituntil {
			sleep 9.543;
			(
				__disabled_vehicle ||
				{([_vehicle, _drop_point] call mso_core_fnc_grounddist < 500)}
			)
		};
		if (__disabled_vehicle) then {
			GVAR(AVAILABLE_VEHICLES) = GVAR(AVAILABLE_VEHICLES) - 1;
			publicVariable QGVAR(AVAILABLE_VEHICLES);
			__inform_player(STR_TYR_DROP_VEHICLEDESTROYED)
			sleep 5;
		};
		__delete_vehicle		
	};
	sleep 20;
	GVAR(TRANSPORTER_IN_THE_AIR) = false;
	publicVariable QGVAR(TRANSPORTER_IN_THE_AIR);
	TRACE("Spawn End");
};
TRACE("End");
TMFPROFILERSTOP;